<template>
  <div id="map_container" @mouseout="handleMouseout"></div>
</template>

<script setup lang="ts">
import { initMap, whiteStyle } from "@/utils"
import { onMounted, watch, computed, ref } from "vue"
import chinaJson from "@/assets/colleges-info.json"

interface Props {
  schools?: string[]
  mapRoom?: number
}

const props = withDefaults(defineProps<Props>(), {
  schools: () => [],
  mapRoom: 5
})
const emit = defineEmits(["update:schools"])
const schools = computed({
  get: () => props.schools,
  set: val => emit("update:schools", val)
})

// 计算高亮和普通学校数据
const normalSchools = computed(() => {
  if (!props.schools || !Array.isArray(props.schools)) return chinaJson
  return chinaJson.filter(college => college && !props.schools.includes(college.name))
})

const highlightedSchools = computed(() => {
  if (!props.schools || !Array.isArray(props.schools)) return []
  return chinaJson.filter(college => college && props.schools.includes(college.name))
})

// 初始化地图
let map: any = null
let view: any = null
const mapCenter = ref([104.1954, 35.8617])

// 普通学校点图层
const normalPointLayer = new mapvgl.PointLayer({
  blend: "default",
  size: 10,
  enablePicked: true, // 是否可以拾取
  selectedIndex: -1, // 选中数据项索引
  selectedColor: "#ff0000", // 选中项颜色
  color: "rgba(255, 75, 75, 0.7)",
  maxZoom: 19,
  minZoom: 3,
  // renderOrder: 3,
  onClick: (e: any) => handlePointClick(e, false),
  onMousemove: (e: any) => handleMousemove(e),
  onRightClick: (e: any) => handlePointRightClick(e, true),
  onDblClick: (e: any) => handlePointRightClick(e, true)
})

const highlightedPointLayer = new mapvgl.CircleLayer({
  type: "bubble",
  blend: "normal",
  size: 6, // 半径
  radius: 12, // 半径
  enablePicked: true,
  selectedIndex: -1,
  selectedSize: 22, // 选中时增大尺寸
  color: "#00F5FF", // 亮青色
  selectedColor: "#FF9D00", // 橙色
  pickingBuffer: 12, // 增大点击判定范围
  maxZoom: 19,
  minZoom: 3,
  animate: true,
  onClick: (e: any) => handlePointClick(e, true),
  onRightClick: (e: any) => handlePointRightClick(e, false),
  onDblClick: (e: any) => handlePointRightClick(e, false)
})

// 学校标签图层
const labelLayer = new mapvgl.TextLayer({
  offset: [0, -20],
  color: "#00F5FF",
  backgroundColor: "rgba(0,0,0,0.7)",
  selectedColor: "#FF9D00",
  fontSize: 12,
  collides: false,
  padding: [4, 8],
  enablePicked: true,
  autoSelect: true,
  onClick: (e: any) => handlePointClick(e, true)
})

const tooltipLayer = new mapvgl.TextLayer({
  offset: [0, -15],
  color: "#34495e",
  fontSize: 8,
  collides: false,
  padding: [4, 8]
})

// 普通学校数据
const normalData = normalSchools.value.map(college => ({
  geometry: {
    type: "Point",
    coordinates: [college.lng, college.lat]
  },
  properties: {
    name: college.name,
    lng: college.lng,
    lat: college.lat,
    introduce: college.introduce
  }
}))
const tooltipContent = ref<{
  name: string
  lng: number | null
  lat: number | null
}>({
  name: "",
  lng: null,
  lat: null
})

// 更新图层数据
const updateLayers = () => {
  // 高亮学校数据
  const highlightedData = highlightedSchools.value.map(college => {
    return {
      geometry: {
        type: "Point",
        coordinates: [college.lng, college.lat]
      },
      properties: {
        name: college.name,
        lng: college.lng,
        lat: college.lat,
        introduce: college.introduce
      }
    }
  })

  // 标签数据（只显示高亮学校的标签）
  const labelData = highlightedSchools.value.map(college => ({
    geometry: {
      type: "Point",
      coordinates: [college.lng, college.lat]
    },
    properties: {
      text: college.name,
      lng: college.lng,
      lat: college.lat,
      introduce: college.introduce
    }
  }))

  normalPointLayer.setData(normalData)
  highlightedPointLayer.setData(highlightedData)
  labelLayer.setData(labelData)

  if (tooltipContent.value.name) {
    const tooltipData = [
      {
        geometry: {
          type: "Point",
          coordinates: [tooltipContent.value.lng, tooltipContent.value.lat]
        },
        properties: {
          text: tooltipContent.value.name
        }
      }
    ]

    tooltipLayer.setData(tooltipData)
  } else {
    tooltipLayer.setData([])
  }
}

// 处理点击事件
const handlePointClick = (e: any, isHighlighted: boolean) => {
  if (e && e.dataItem) {
    highlightedPointLayer.setOptions({
      selectedIndex: -1
    })
    const college = e.dataItem.properties
    if (college) {
      // 关闭已存在的infoWindow
      map.closeInfoWindow()

      mapCenter.value = new BMapGL.Point(college.lng, college.lat)
      map.centerAndZoom(mapCenter.value, 10)

      const opts = {
        width: 200,
        height: 100,
        title: college.name ?? college.text,
        message: college.name ?? college.text
      }
      const infoWindow = new BMapGL.InfoWindow(college.introduce, opts)

      infoWindow.addEventListener("open", function () {
        // 获取内容容器元素
        var scrollDiv = document.querySelector(".BMap_bubble_content")
        if (scrollDiv) {
          // 阻止滚轮事件冒泡
          function handleWheel(e: Event) {
            e.stopPropagation() // 阻止事件冒泡，避免地图缩放
          }
          scrollDiv.addEventListener("wheel", handleWheel) // 现代浏览器（wheel）
          scrollDiv.addEventListener("mousewheel", handleWheel) // 旧版（mousewheel）
        }
      })
      map.openInfoWindow(infoWindow, mapCenter.value)
    }
  }
}

const handleMousemove = (e: any) => {
  if (e && e.dataItem) {
    const college = e.dataItem.properties
    if (normalSchools.value.includes(college.name)) {
      return
    }
    if (college) {
      // 更新弹窗内容
      tooltipContent.value.name = college.name
      tooltipContent.value.lng = college.lng
      tooltipContent.value.lat = college.lat
      updateLayers()
    }
  }
}

const handlePointRightClick = (e: any, isSelected: boolean) => {
  console.log("handlePointRightClick", e, isSelected)
  if (e && e.dataItem) {
    const college = e.dataItem.properties
    if (college) {
      if (isSelected) {
        schools.value.push(college.name)
      } else {
        schools.value = schools.value.filter(item => item !== college.name)
      }
    }
  }
}
const handleMouseout = () => {
  tooltipContent.value.name = ""
  tooltipContent.value.lng = null
  tooltipContent.value.lat = null
  updateLayers()
}

const init = () => {
  if (map) {
    map.destroy() // 清理旧的地图实例
  }
  if (view) {
    view.destroy() // 清理旧的视图实例
  }

  map = initMap({
    tilt: 0,
    heading: 0,
    center: mapCenter.value,
    zoom: props.mapRoom,
    style: whiteStyle,
    skyColors: [
      "rgba(226, 237, 248, 0)", // 地面颜色
      "rgba(186, 211, 252, 1)" // 天空颜色
    ],
    // 添加性能相关配置
    enableAutoResize: true,
    preserveDrawingBuffer: false,
    maxZoom: 19,
    minZoom: 3
  })
  // 创建视图实例
  view = new mapvgl.View({
    map: map
  })

  // 添加图层到视图
  view.addLayer(normalPointLayer)
  view.addLayer(highlightedPointLayer)
  view.addLayer(labelLayer)
  view.addLayer(tooltipLayer)

  // 初始更新图层
  updateLayers()

  // 监听地图点击事件
  // map.addEventListener("click", function (e) {
  //   var pt = e.point // 获取点击的经纬度坐标

  //   // 创建地理编码实例
  //   const geocoder = new BMap.Geocoder()
  //   geocoder.getLocation(pt, function (rs) {
  //     console.log("点击的经纬度：", pt)
  //     console.log("点击的详细地址：", rs)
  //     if (rs) {
  //       // 从地址信息中提取省份名称
  //       var province = rs.addressComponents.province
  //       console.log("点击的省份：", province)
  //       alert("当前点击的省份是：" + province)
  //     } else {
  //       console.log("未解析到地址信息")
  //     }
  //   })
  // })
}

const setMapCenter = (college: Record<string, any>) => {
  const collegeItem = chinaJson.find(item => item.name === college.name)

  if (!collegeItem) return

  // 关闭已存在的infoWindow
  map.closeInfoWindow()

  // 点击时居中并放大
  mapCenter.value = new BMapGL.Point(college.lng, college.lat)
  map.centerAndZoom(mapCenter.value, 12)

  const opts = {
    width: 200, // 信息窗口宽度
    height: 100, // 信息窗口高度
    title: collegeItem.name, // 信息窗口标题
    message: collegeItem.name
  }
  const infoWindow = new BMapGL.InfoWindow(collegeItem.introduce, opts)

  // 监听InfoWindow打开事件
  infoWindow.addEventListener("open", function () {
    // 获取内容容器元素
    var scrollDiv = document.querySelector(".BMap_bubble_content")
    if (scrollDiv) {
      // 阻止滚轮事件冒泡
      function handleWheel(e: Event) {
        e.stopPropagation() // 阻止事件冒泡，避免地图缩放
      }
      scrollDiv.addEventListener("wheel", handleWheel) // 现代浏览器（wheel）
      scrollDiv.addEventListener("mousewheel", handleWheel) // 旧版（mousewheel）
    }
  })
  map.openInfoWindow(infoWindow, mapCenter.value)
}

onMounted(() => {
  init()
})

// 监听学校数据变化
watch(
  () => props.schools,
  () => {
    updateLayers()
  },
  { deep: true }
)

defineExpose({
  setMapCenter: (college: Record<string, any>) => setMapCenter(college)
})
</script>

<style scoped lang="scss">
#map_container {
  width: 100%;
  height: 100%;

  :deep(.anchorBL) {
    display: none;
  }

  :deep(.BMap_bubble_pop) {
    z-index: 1000;
    overflow: hidden;
  }
}

:deep(.mapvgl-label) {
  pointer-events: none;
  white-space: nowrap;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
</style>
